package com.zlyx.easy.web.web.service.impl;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zlyx.easy.core.annotations.Desc;
import com.zlyx.easy.core.map.CommonMap;
import com.zlyx.easy.core.model.Page;
import com.zlyx.easy.core.tool.EasyBuffer;
import com.zlyx.easy.core.tool.Ops;
import com.zlyx.easy.core.utils.LogUtils;
import com.zlyx.easy.core.utils.ObjectUtils;
import com.zlyx.easy.database.annotations.TableBean;
import com.zlyx.easy.database.enums.SqlType;
import com.zlyx.easy.database.local.ReturnType;
import com.zlyx.easy.database.supports.SqlAssembler;
import com.zlyx.easy.database.supports.SqlSupport;
import com.zlyx.easy.mybatis.mapper.MybatisMapper;
import com.zlyx.easy.web.web.mybatis.AbstractMapper;
import com.zlyx.easy.web.web.service.AbstractService;

/**
 * @Auth 赵光
 * @Describle
 * @Date 2019年1月4日 下午9:03:27
 */
public abstract class AbstractServiceImpl<Mapper extends AbstractMapper<T>, T> extends ServiceImpl<Mapper, T>
		implements AbstractService<Mapper, T> {

	@Autowired
	private MybatisMapper mybatisMapper;

	@Override
	@SuppressWarnings("unchecked")
	@Desc("不带总数的分页")
	public List<T> pageNoTotal(String sql, int pageSize, int pageNum) {
		ReturnType.setType(this.getTClass());
		return (List<T>) mybatisMapper.page(sql, pageSize, pageNum);
	}

	@Override
	@Desc("分页")
	public Page<T> page(String sql, int pageSize, int pageNum) {
		String countSql = sql.replace(sql.substring(sql.indexOf("select") + 6, sql.indexOf("from")), " count(*) ");
		Object count = mybatisMapper.selectOne(countSql);
		if (ObjectUtils.isEmpty(count) || (Long) count == 0) {
			LogUtils.warn(this.getClass(), "No results return!");
			return null;
		}
		ReturnType.setType(this.getTClass());
		List<?> data = mybatisMapper.page(sql, pageSize, pageNum);
		return new Page<>(data, (Long) count);
	}

	@Override
	@SuppressWarnings("unchecked")
	@Desc("查询")
	public List<T> select(String sql) {
		ReturnType.setType(this.getTClass());
		return (List<T>) mybatisMapper.select(sql);
	}

	@Override
	@SuppressWarnings("unchecked")
	@Desc("查询")
	public T selectOne(String sql) {
		ReturnType.setType(this.getTClass());
		return (T) mybatisMapper.selectOne(sql);
	}

	@Override
	@Desc("查询")
	public long selectCount(String sql) {
		ReturnType.setType(this.getTClass());
		return (long) mybatisMapper.selectOne(sql);
	}

	@Override
	@Desc("更新")
	public boolean update(String sql) {
		try {
			mybatisMapper.update(sql);
			return true;
		} catch (Exception e) {
			LogUtils.err(e);
		}
		return false;
	}

	@Override
	@Desc("更新")
	public boolean updateByIds(List<Object> ids, String sqlFragment) {
		CommonMap sqlElements = CommonMap.newMap();
		TableBean tableBean = this.getTClass().getAnnotation(TableBean.class);
		if (ObjectUtils.isEmpty(tableBean)) {
			LogUtils.err(this.getClass(), new Exception("实体类上没有声明@TableBean注解，无法使用此方法!"));
			return false;
		}
		sqlElements.addValue(SqlSupport.TYPENAME, SqlType.Update.toString())
				.addValue(SqlSupport.TABLENAME, tableBean.value()).addValue(SqlSupport.CONTENT, sqlFragment)
				.addValue(SqlSupport.CONDITON, EasyBuffer.newString("where id in (", Ops.toString(ids), ")"));
		return delete(SqlAssembler.assemble(this, sqlElements));
	}

	@Override
	@Desc("删除")
	public boolean delete(String sql) {
		try {
			mybatisMapper.delete(sql);
			return true;
		} catch (Exception e) {
			LogUtils.err(e);
		}
		return false;
	}

	@Override
	@Desc("删除")
	public boolean deleteByIds(List<Object> ids) {
		CommonMap sqlElements = CommonMap.newMap();
		TableBean tableBean = this.getTClass().getAnnotation(TableBean.class);
		if (ObjectUtils.isEmpty(tableBean)) {
			LogUtils.err(this.getClass(), new Exception("实体类上没有声明@TableBean注解，无法使用此方法!"));
			return false;
		}
		sqlElements.addValue(SqlSupport.TYPENAME, SqlType.Delete.toString())
				.addValue(SqlSupport.TABLENAME, tableBean.value())
				.addValue(SqlSupport.CONDITON, EasyBuffer.newString("where id in (", Ops.toString(ids), ")"));
		return delete(SqlAssembler.assemble(this, sqlElements));
	}

	@Override
	@Desc("新增")
	public boolean insert(String sql) {
		try {
			mybatisMapper.insert(sql);
			return true;
		} catch (Exception e) {
			LogUtils.err(e);
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	public Class<T> getTClass() {
		return (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}
}